2022_derbyshire_dr_who_theme.py

#

SPDX-FileCopyrightText: 2022 Ji Eun Kim & Khawla Rachadi SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be

SPDX-License-Identifier: GPL-3.0-or-later

#

Script written in blender 3.3.0 by Jieun/Khawla 19.01.23

import bpy
import bmesh
import random
#

---------- Clean Up ----------#

#
def clean():
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.delete()
    bpy.ops.outliner.orphans_purge()


clean()
#

--------------------------- Create Segements + Define Points ---------------------------# ------------------------------------------------------------------------------------------#

#

CUBE EDGE B1

sg_x00 = []
for x in range(31):
    sg_x00.append((x, 0, 0))
#

CUBE EDGE B2

sg_30y0 = []
for y in range(31):
    sg_30y0.append((30, y, 0))
#

CUBE EDGE B3

sg_x300 = []
for x in range(31):
    sg_x300.append((x, 30, 0))
#

CUBE EDGE B4

sg_0y0 = []
for y in range(31):
    sg_0y0.append((0, y, 0))
#

CUBE EDGE V1

sg_00z = []
for z in range(31):
    sg_00z.append((0, 0, z))
#

CUBE EDGE V2

sg_300z = []
for z in range(31):
    sg_300z.append((30, 0, z))
#

CUBE EDGE V3

sg_3030z = []
for z in range(31):
    sg_3030z.append((30, 30, z))
#

CUBE EDGE V4

sg_030z = []
for z in range(31):
    sg_030z.append((0, 30, z))


sg_x030 = []
for x in range(31):
    sg_x030.append((x, 0, 30))


sg_x3030 = []
for x in range(31):
    sg_x3030.append((x, 30, 30))


sg_0y30 = []
for y in range(31):
    sg_0y30.append((0, y, 30))


sg_30y30 = []
for y in range(31):
    sg_30y30.append((30, y, 30))
#

---------- List of the Segments ----------#

segments = [
    sg_x00,
    sg_30y0,
    sg_x300,
    sg_0y0,
    sg_00z,
    sg_300z,
    sg_3030z,
    sg_030z,
    sg_x030,
    sg_x3030,
    sg_0y30,
    sg_30y30,
]
#

-----------------------------------------------------------------------------------------# ---------------------------------------- Base ------------------------------------------# -----------------------------------------------------------------------------------------#

#

------------------------- Random choice of Consecutive points -------------------------# -----------------------------------------------------------------------------------------#

#
def Base():
#

---------- Choosing 3 Random Segments ----------#

    S1, S2, S3 = random.sample(segments, 3)
#

---------- Random choice of Consecutive points ----------#

#

Choosing the first points

    i1_1 = random.randint(0, 16)
    e1_1 = random.randint(6, 14)
    res1_1 = []

    for r in range(e1_1):
        res1_1.append(S1[i1_1 + r])
#

print result

    print("The consecutive element paired list is : " + str(res1_1))
#

Choosing the second points

    i1_2 = random.randint(0, 16)
    e1_2 = random.randint(6, 14)

    res1_2 = []

    for r in range(e1_2):
        res1_2.append(S2[i1_2 + r])
#

Choosing the third points

    i1_3 = random.randint(0, 16)
    e1_3 = random.randint(6, 14)

    res1_3 = []

    for r in range(e1_3):
        res1_3.append(S3[i1_3 + r])
#

------------------------- Connecting the points in to edges ---------------------------# -----------------------------------------------------------------------------------------#

#

Making the first edge

    myVerticles1_1 = []
    myEdges1_1 = []

    for a in range(e1_1):
        myVerticles1_1.append(res1_1[a])
        myEdges1_1.append((a, a + 1))
        print("a", a, "/", a + 1)

    print("Edge", len(myEdges1_1), ":", myEdges1_1[:-1])
    print("myVerticles", len(myVerticles1_1), ":", myVerticles1_1)
#

creation of the mesh and the object

    myMesh1_1 = bpy.data.meshes.new("cubeedge1-1")
    myObject1_1 = bpy.data.objects.new("edge1-1", myMesh1_1)
#

link object to collection

    myCollection1_1 = bpy.context.collection
    myCollection1_1.objects.link(myObject1_1)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh1_1.from_pydata(myVerticles1_1, myEdges1_1[:-1], [])
#

Making the Second edge

    myVerticles1_2 = []
    myEdges1_2 = []

    for a in range(e1_2):
        myVerticles1_2.append(res1_2[a])
        myEdges1_2.append([a, a + 1])
#

creation of the mesh and the object

    myMesh1_2 = bpy.data.meshes.new("cubeedge1-2")
    myObject1_2 = bpy.data.objects.new("edge1-2", myMesh1_2)
#

link object to collection

    myCollection1_2 = bpy.context.collection
    myCollection1_2.objects.link(myObject1_2)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh1_2.from_pydata(myVerticles1_2, myEdges1_2[:-1], [])
#

Making the Third edge

    myVerticles1_3 = []
    myEdges1_3 = []

    for a in range(e1_3):
        myVerticles1_3.append(res1_3[a])
        myEdges1_3.append([a, a + 1])
#

creation of the mesh and the object

    myMesh1_3 = bpy.data.meshes.new("cubeedge1-3")
    myObject1_3 = bpy.data.objects.new("edge1-3", myMesh1_3)
#

link object to collection

    myCollection1_3 = bpy.context.collection
    myCollection1_3.objects.link(myObject1_3)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh1_3.from_pydata(myVerticles1_3, myEdges1_3[:-1], [])
#

---------- Joining the edges in to one object ----------#

    objs = bpy.data.objects

    line1_1 = objs["edge1-1"]
    line1_2 = objs["edge1-2"]
    line1_3 = objs["edge1-3"]

    line1_1.select_set(True)
    line1_2.select_set(True)
    line1_3.select_set(True)
    bpy.context.view_layer.objects.active = bpy.data.objects["edge1-1"]

    bpy.ops.object.join()

    bpy.ops.object.editmode_toggle()
#

Undo selecting

    bpy.context.active_object.select_set(False)
#

--------------------------------- Looping the edges -----------------------------------# -----------------------------------------------------------------------------------------#

#

------------ Bridge edge loop parameters ------------#

    cuts_1 = random.randint(40, 80)

    bpy.ops.mesh.bridge_edge_loops(
        type="CLOSED",
        use_merge=False,
        merge_factor=0.5,
        twist_offset=0,
        number_cuts=cuts_1,
        interpolation="PATH",
        smoothness=0.5,
        profile_shape_factor=0,
        profile_shape="SMOOTH",
    )
#

------------------ Giving Thickness ------------------#

    bpy.ops.object.modifier_add(type="SOLIDIFY")
    bpy.context.object.modifiers["Solidify"].thickness = 0.5  # [mm]
    bpy.context.object.modifiers["Solidify"].offset = 0

    bpy.ops.object.editmode_toggle()


Base()
#

-----------------------------------------------------------------------------------------# --------------------------------------- Hissing ---------------------------------------# -----------------------------------------------------------------------------------------#

#

------------------------- Random choice of Consecutive points -------------------------# -----------------------------------------------------------------------------------------#

#
def Hissing():
#

---------- Choosing 3 Random Segments ----------#

    B1, B2, B3 = random.sample(segments, 3)
#

---------- Random choice of Consecutive points ----------#

#

Choosing the first poinnts

    i2_1 = random.randint(0, 26)
    e2_1 = random.randint(3, 5)

    res2_1 = []

    for r in range(e2_1):
        res2_1.append(B1[i2_1 + r])
#

Choosing the second points

    i2_2 = random.randint(0, 26)
    e2_2 = random.randint(3, 5)

    res2_2 = []

    for r in range(e2_2):
        res2_2.append(B2[i2_2 + r])
#

Choosing the third points

    i2_3 = random.randint(0, 26)
    e2_3 = random.randint(3, 5)

    res2_3 = []

    for r in range(e2_3):
        res2_3.append(B3[i2_3 + r])
#

------------------------- Connecting the points in to edges ---------------------------# -----------------------------------------------------------------------------------------#

#

Making the first edge

    myVerticles2_1 = []
    myEdges2_1 = []

    for a in range(e2_1):
        myVerticles2_1.append(res2_1[a])
        myEdges2_1.append((a, a + 1))
        print("a", a, "/", a + 1)
#

creation of the mesh and the object

    myMesh2_1 = bpy.data.meshes.new("cubeedge2-1")
    myObject2_1 = bpy.data.objects.new("edge2-1", myMesh2_1)
#

link object to collection

    myCollection2_1 = bpy.context.collection
    myCollection2_1.objects.link(myObject2_1)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh2_1.from_pydata(myVerticles2_1, myEdges2_1[:-1], [])
#

Making the Second edge

    myVerticles2_2 = []
    myEdges2_2 = []

    for a in range(e2_2):
        myVerticles2_2.append(res2_2[a])
        myEdges2_2.append([a, a + 1])
#

creation of the mesh and the object

    myMesh2_2 = bpy.data.meshes.new("cubeedge2-2")
    myObject2_2 = bpy.data.objects.new("edge2-2", myMesh2_2)
#

link object to collection

    myCollection2_2 = bpy.context.collection
    myCollection2_2.objects.link(myObject2_2)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh2_2.from_pydata(myVerticles2_2, myEdges2_2[:-1], [])
#

Making the Third edge

    myVerticles2_3 = []
    myEdges2_3 = []

    for a in range(e2_3):
        myVerticles2_3.append(res2_3[a])
        myEdges2_3.append([a, a + 1])
#

creation of the mesh and the object

    myMesh2_3 = bpy.data.meshes.new("cubeedge2-3")
    myObject2_3 = bpy.data.objects.new("edge2-3", myMesh2_3)
#

link object to collection

    myCollection2_3 = bpy.context.collection
    myCollection2_3.objects.link(myObject2_3)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh2_3.from_pydata(myVerticles2_3, myEdges2_3[:-1], [])
#

---------- Joining the edges in to one object ----------#

    objs = bpy.data.objects

    line2_1 = objs["edge2-1"]
    line2_2 = objs["edge2-2"]
    line2_3 = objs["edge2-3"]

    line2_1.select_set(True)
    line2_2.select_set(True)
    line2_3.select_set(True)
    bpy.context.view_layer.objects.active = bpy.data.objects["edge2-1"]

    bpy.ops.object.join()
#

Undo selecting

    bpy.context.active_object.select_set(False)

    bpy.ops.object.editmode_toggle()
#

--------------------------------- Looping the edges -----------------------------------# -----------------------------------------------------------------------------------------#

#

------------ Bridge edge loop parameters ------------#

    cuts_2 = random.randint(30, 60)

    bpy.ops.mesh.bridge_edge_loops(
        type="CLOSED",
        use_merge=False,
        merge_factor=0.5,
        twist_offset=0,
        number_cuts=cuts_2,
        interpolation="PATH",
        smoothness=0.5,
        profile_shape_factor=-0.5,
        profile_shape="SMOOTH",
    )
#

------------------ Giving Thickness ------------------#

    bpy.ops.object.modifier_add(type="SOLIDIFY")
    bpy.context.object.modifiers["Solidify"].thickness = 0.5
    bpy.context.object.modifiers["Solidify"].offset = 0

    bpy.ops.object.editmode_toggle()


Hissing()
#

-----------------------------------------------------------------------------------------# --------------------------------------- Melody ----------------------------------------# -----------------------------------------------------------------------------------------#

#

------------------------- Random choice of Consecutive points -------------------------# -----------------------------------------------------------------------------------------#

#
def Melody():
#

---------- Choosing 3 Random Segments ----------#

    W1, W2, W3 = random.sample(segments, 3)
#

---------- Random choice of Consecutive points ----------#

#

Choosing the first points

    i3_1 = random.randint(0, 16)
    e3_1 = random.randint(5, 15)

    res3_1 = []

    for r in range(e3_1):
        res3_1.append(W1[i3_1 + r])
#

Choosing the second points

    i3_2 = random.randint(0, 16)
    e3_2 = random.randint(5, 15)

    res3_2 = []

    for r in range(e3_2):
        res3_2.append(W2[i3_2 + r])
#

Choosing the third points

    i3_3 = random.randint(0, 16)
    e3_3 = random.randint(5, 15)

    res3_3 = []

    for r in range(e3_3):
        res3_3.append(W3[i3_3 + r])
#

------------------------- Connecting the points in to edges ---------------------------# -----------------------------------------------------------------------------------------#

#

Making the first edge

    myVerticles3_1 = []
    myEdges3_1 = []

    for a in range(e3_1):
        myVerticles3_1.append(res3_1[a])
        myEdges3_1.append((a, a + 1))
        print("a", a, "/", a + 1)
#

creation of the mesh and the object

    myMesh3_1 = bpy.data.meshes.new("cubeedge3-1")
    myObject3_1 = bpy.data.objects.new("edge3-1", myMesh3_1)
#

link object to collection

    myCollection3_1 = bpy.context.collection
    myCollection3_1.objects.link(myObject3_1)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh3_1.from_pydata(myVerticles3_1, myEdges3_1[:-1], [])
#

Making the Second edge

    myVerticles3_2 = []
    myEdges3_2 = []

    for a in range(e3_2):
        myVerticles3_2.append(res3_2[a])
        myEdges3_2.append([a, a + 1])
#

creation of the mesh and the object

    myMesh3_2 = bpy.data.meshes.new("cubeedge3-2")
    myObject3_2 = bpy.data.objects.new("edge3-2", myMesh3_2)
#

link object to collection

    myCollection3_2 = bpy.context.collection
    myCollection3_2.objects.link(myObject3_2)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh3_2.from_pydata(myVerticles3_2, myEdges3_2[:-1], [])
#

Making the Third edge

    myVerticles3_3 = []
    myEdges3_3 = []

    for a in range(e3_3):
        myVerticles3_3.append(res3_3[a])
        myEdges3_3.append([a, a + 1])
#

creation of the mesh and the object

    myMesh3_3 = bpy.data.meshes.new("cubeedge3-3")
    myObject3_3 = bpy.data.objects.new("edge3-3", myMesh3_3)
#

link object to collection

    myCollection3_3 = bpy.context.collection
    myCollection3_3.objects.link(myObject3_3)
#

fill the mesh with the verticles information (position of verticles & connection to make edges)

    myMesh3_3.from_pydata(myVerticles3_3, myEdges3_3[:-1], [])
#

---------- Joining the edges in to one object ----------#

    objs = bpy.data.objects

    line3_1 = objs["edge3-1"]
    line3_2 = objs["edge3-2"]
    line3_3 = objs["edge3-3"]

    line3_1.select_set(True)
    line3_2.select_set(True)
    line3_3.select_set(True)
    bpy.context.view_layer.objects.active = bpy.data.objects["edge3-1"]

    bpy.ops.object.join()

    bpy.ops.object.editmode_toggle()
#

Undo selecting

    bpy.context.active_object.select_set(False)
#

--------------------------------- Looping the edges -----------------------------------# -----------------------------------------------------------------------------------------#

#

------------ Bridge edge loop parameters ------------#

    cuts_3 = random.randint(40, 80)

    bpy.ops.mesh.bridge_edge_loops(
        type="CLOSED",
        use_merge=False,
        merge_factor=0.5,
        twist_offset=0,
        number_cuts=cuts_3,
        interpolation="PATH",
        smoothness=0.5,
        profile_shape_factor=0,
        profile_shape="SMOOTH",
    )
#

------------------ Giving Thickness ------------------#

    bpy.ops.object.modifier_add(type="SOLIDIFY")
    bpy.context.object.modifiers["Solidify"].thickness = 0.6  # [mm]
    bpy.context.object.modifiers["Solidify"].offset = 0

    bpy.ops.object.editmode_toggle()


Melody()
#

----------- apply modifiers to all objects -----------#

#
def apply_modifiers(obj):
    ctx = bpy.context.copy()
    ctx["object"] = obj
    for _, m in enumerate(obj.modifiers):
        try:
            ctx["modifier"] = m
            bpy.ops.object.modifier_apply(ctx, modifier=m.name)
        except RuntimeError:
            print(f"Error applying {m.name} to {obj.name}, removing it instead.")
            obj.modifiers.remove(m)

    for m in obj.modifiers:
        obj.modifiers.remove(m)
#

apply modifiers on every object in your scene

for o in bpy.data.objects:
    apply_modifiers(o)
#

--------------------------------- Loop Cut of the Melody ------------------------------

-----------------------------------------------------------------------------------------

loopcutob = objs[‘edge3-1’] loopcutob.select_set(True)

bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type=’FACE’)

def make_loop_cut(number_cuts=1):

bpy.ops.object.editmode_toggle()

def view3d_find( return_area = False ):
    # returns first 3d view, normally we get from context
    for area in bpy.context.window.screen.areas:
        if area.type == 'VIEW_3D':
            v3d = area.spaces[0]
            rv3d = v3d.region_3d
            for region in area.regions:
                if region.type == 'WINDOW':
                    if return_area: return region, rv3d, v3d, area
                    return region, rv3d, v3d
    return None, None

region, rv3d, v3d, area = view3d_find(True)

override = {
    'scene'  : bpy.context.scene,
    'region' : region,
    'area'   : area,
    'space'  : v3d
}
bpy.ops.mesh.loopcut(
    override, 
    MESH_OT_loopcut = {
        "object_index"          : 0,
        "number_cuts"           : number_cuts,
        "smoothness"            : 0,     
        "falloff"               : 'SMOOTH',  # Was 'INVERSE_SQUARE' that does not exist
        "object_index"          : 0,
        "edge_index"            : 2,
        "mesh_select_mode_init" : (True, False, False)
    }
)
bpy.ops.object.editmode_toggle()

make_loop_cut(30)

bpy.ops.object.editmode_toggle()